<template>
  <div class="app-container">
    <el-form
      :model="queryParams"
      ref="queryForm"
      size="small"
      :inline="true"
      v-show="showSearch"
      label-width="68px"
    >
      <el-form-item label="DID" prop="did">
        <el-input
          v-model="queryParams.did"
          placeholder="请输入DID"
          clearable
          @keyup.enter.native="handleQuery"
        />
      </el-form-item>

      <el-form-item>
        <el-button
          type="primary"
          icon="el-icon-search"
          size="mini"
          @click="handleQuery"
        >搜索
        </el-button
        >
        <el-button icon="el-icon-refresh" size="mini" @click="resetQuery"
        >重置
        </el-button
        >
      </el-form-item>
    </el-form>

    <el-row :gutter="10" class="mb8">
      <el-col :span="1.5">
        <el-button
          type="primary"
          plain
          icon="el-icon-plus"
          size="mini"
          @click="handleAdd"
          v-hasPermi="['access:user_access:add']"
        >新增
        </el-button>
      </el-col>
      <el-col :span="1.5">
        <el-button
          type="success"
          plain
          icon="el-icon-edit"
          size="mini"
          :disabled="single"
          @click="handleUpdate"
          v-hasPermi="['access:user_access:edit']"
        >修改
        </el-button>
      </el-col>
      <el-col :span="1.5">
        <el-button
          type="danger"
          plain
          icon="el-icon-delete"
          size="mini"
          :disabled="multiple"
          @click="handleDelete"
          v-hasPermi="['access:user_access:remove']"
        >删除
        </el-button>
      </el-col>
      <el-col :span="1.5">
        <el-button
          type="warning"
          plain
          icon="el-icon-download"
          size="mini"
          @click="handleExport"
          v-hasPermi="['access:user_access:export']"
        >导出
        </el-button>
      </el-col>
      <right-toolbar
        :showSearch.sync="showSearch"
        @queryTable="getList"
      ></right-toolbar>
    </el-row>

    <el-table
      v-loading="loading"
      :data="user_accessList"
      @selection-change="handleSelectionChange"
    >
      <el-table-column type="selection" width="55" align="center"/>
      <el-table-column label="DID" align="center" prop="did"/>
      <el-table-column label="DID类型" align="center" prop="type">
        <template slot-scope="scope">
          <dict-tag :options="dict.type.did_type" :value="scope.row.type"/>
        </template>
      </el-table-column>
      <el-table-column label="发布者" align="center" prop="issuer"/>
      <el-table-column
        label="起始日期"
        align="center"
        prop="validFrom"
        width="180"
      >
        <template slot-scope="scope">
          <span>{{ parseTime(scope.row.validFrom, "{y}-{m}-{d}") }}</span>
        </template>
      </el-table-column>
      <el-table-column
        label="结束日期"
        align="center"
        prop="validUntil"
        width="180"
      >
        <template slot-scope="scope">
          <span>{{ parseTime(scope.row.validUntil, "{y}-{m}-{d}") }}</span>
        </template>
      </el-table-column>
      <el-table-column label="用户属性" align="center" prop="userProperty"/>
      <el-table-column
        label="用户密钥"
        align="center"
        prop="userKeys"
        show-overflow-tooltip
      />
      <el-table-column label="是否上链" align="center" prop="onChain">
        <template slot-scope="scope">
          <dict-tag :options="dict.type.on_chain" :value="scope.row.onChain"/>
        </template>
      </el-table-column>
      <el-table-column
        label="创建时间"
        align="center"
        prop="createTime"
        width="180"
      >
        <template slot-scope="scope">
          <span>{{ parseTime(scope.row.createTime, "{y}-{m}-{d}") }}</span>
        </template>
      </el-table-column>
      <el-table-column
        label="更新时间"
        align="center"
        prop="updateTime"
        width="180"
      >
        <template slot-scope="scope">
          <span>{{ parseTime(scope.row.updateTime, "{y}-{m}-{d}") }}</span>
        </template>
      </el-table-column>
      <el-table-column
        label="操作"
        align="center"
        class-name="small-padding fixed-width"
      >
        <template slot-scope="scope">
          <el-button
            size="mini"
            type="text"
            icon="el-icon-edit"
            @click="handleUpdate(scope.row)"
            v-hasPermi="['access:user_access:edit']"
          >修改
          </el-button>
          <el-button
            size="mini"
            type="text"
            icon="el-icon-s-platform"
            @click="submitAccess(scope.row)"
            v-hasPermi="['access:user_access:edit']"
          >访问设备
          </el-button>
          <!--          <el-button-->
          <!--            size="mini"-->
          <!--            type="text"-->
          <!--            icon="el-icon-edit"-->
          <!--            @click="openSSHDialog(scope.row)"-->
          <!--            v-hasPermi="['access:user_access:edit']"-->
          <!--          >远程登录-->
          <!--          </el-button>-->
          <!--          <el-button-->
          <!--            size="mini"-->
          <!--            type="text"-->
          <!--            icon="el-icon-edit"-->
          <!--            @click="remoteUserCheck(scope.row)"-->
          <!--            v-hasPermi="['access:user_access:edit']"-->
          <!--            >远程用户-->
          <!--          </el-button>-->
          <el-button
            size="mini"
            type="text"
            icon="el-icon-delete"
            @click="handleDelete(scope.row)"
            v-hasPermi="['access:user_access:remove']"
          >删除
          </el-button>
        </template>
      </el-table-column>
    </el-table>

    <pagination
      v-show="total > 0"
      :total="total"
      :page.sync="queryParams.pageNum"
      :limit.sync="queryParams.pageSize"
      @pagination="getList"
    />

    <!-- 添加或修改用户访问控制对话框 -->
    <el-dialog :title="title" :visible.sync="open" width="500px" append-to-body>
      <el-form ref="form" :model="form" :rules="rules" label-width="80px">
        <!--        <el-form-item label="DID" prop="did">-->
        <!--          <el-input v-model="form.did" placeholder="请输入DID"/>-->
        <!--        </el-form-item>-->
        <el-form-item label="用户DID" prop="did">
          <el-select v-model="form.did" placeholder="请选择" style="min-width: 260px">
            <el-option
              v-for="item in didList"
              v-if="item.type ===1"
              :key="item.did"
              :label="item.did+'  '+item.name"
              :value="item.did">
              <span style="float: left">{{ item.did }}</span>
              <span style="float: right; color: #8492a6; font-size: 13px">{{ item.name }}</span>
            </el-option>
          </el-select>
        </el-form-item>
        <el-form-item label="起始日期" prop="validFrom">
          <el-date-picker
            clearable
            v-model="form.validFrom"
            type="date"
            value-format="yyyy-MM-dd"
            placeholder="请选择起始日期"
            style="min-width: 260px"
          >
          </el-date-picker>
        </el-form-item>
        <el-form-item label="结束日期" prop="validUntil">
          <el-date-picker
            clearable
            v-model="form.validUntil"
            type="date"
            value-format="yyyy-MM-dd"
            placeholder="请选择结束日期"
            style="min-width: 260px"
          >
          </el-date-picker>
        </el-form-item>
        <el-form-item label="用户属性">
          <div class="add-property-btn">
            <el-button
              type="primary"
              icon="el-icon-plus"
              size="small"
              @click="addProperty"
            >添加属性
            </el-button
            >
          </div>

          <table class="property-table">
            <thead>
            <tr>
              <th width="45%">属性名</th>
              <th width="45%">属性值</th>
              <th width="10%">操作</th>
            </tr>
            </thead>
            <tbody>
            <tr
              v-for="(property, index) in form.userProperties || []"
              :key="index"
            >
              <td>
                <el-select
                  v-model="property.key"
                  placeholder="请选择属性名"
                  class="property-select"
                  filterable
                  clearable
                  @change="handleKeyChange(index)"
                  :loading="loadingKeys"
                >
                  <el-option
                    v-for="item in propertyKeys"
                    :key="item"
                    :label="item"
                    :value="item"
                  ></el-option>
                </el-select>
              </td>
              <td>
                <el-select
                  v-model="property.value"
                  placeholder="请选择属性值"
                  class="property-select"
                  filterable
                  clearable
                  :loading="loadingValues[index]"
                  :disabled="!property.key"
                >
                  <el-option
                    v-for="item in propertyValues[index]"
                    :key="item"
                    :label="item"
                    :value="item"
                  ></el-option>
                </el-select>
              </td>
              <td>
                <el-button
                  type="danger"
                  icon="el-icon-delete"
                  size="small"
                  circle
                  @click="removeProperty(index)"
                ></el-button>
              </td>
            </tr>
            <tr
              v-if="!form.userProperties || form.userProperties.length === 0"
            >
              <td colspan="3" style="text-align: center; color: #909399">
                暂无属性，请点击"添加属性"按钮
              </td>
            </tr>
            </tbody>
          </table>

          <!-- <div style="margin-top: 10px; font-size: 12px; color: #909399">
            提示：属性名和属性值从接口动态获取
          </div> -->
        </el-form-item>
      </el-form>
      <div slot="footer" class="dialog-footer">
        <el-button type="primary" @click="submitForm">确 定</el-button>
        <el-button @click="cancel">取 消</el-button>
      </div>
    </el-dialog>

    <el-dialog
      title="访问设备"
      :visible.sync="openAccess"
      width="500px"
      append-to-body
    >
      <el-form
        ref="formAccess"
        :model="formAccess"
        :rules="rulesAccess"
        label-width="80px"
      >
        <!--        <el-form-item label="设备DID" prop="deviceDID">-->
        <!--          <el-input v-model="formAccess.deviceDID" placeholder="设备DID"/>-->
        <!--        </el-form-item>-->
        <el-form-item label="设备DID" prop="deviceDID">
          <el-select v-model="formAccess.deviceDID" placeholder="请选择" style="min-width: 260px">
            <el-option
              v-for="item in didList"
              v-if="item.type ===0"
              :key="item.did"
              :label="item.did+'  '+item.name"
              :value="item.did">
              <span style="float: left">{{ item.did }}</span>
              <span style="float: right; color: #8492a6; font-size: 13px">{{ item.name }}</span>
            </el-option>
          </el-select>
        </el-form-item>
      </el-form>
      <div slot="footer" class="dialog-footer">
        <el-button type="primary" @click="submitFormAccess">确 定</el-button>
        <el-button @click="cancel">取 消</el-button>
      </div>
    </el-dialog>

    <!-- ssh弹窗 -->
    <el-dialog
      title="SSH 终端"
      :visible.sync="dialogVisible"
      width="60%"
      top="5vh"
      @opened="initTerminal"
    >
      <div
        ref="terminal"
        style="
          width: 100%;
          height: 500px;
          background: black;
          border-radius: 6px;
        "
      ></div>
    </el-dialog>
  </div>
</template>
<style>
.el-tooltip__popper {
  max-width: 700px;
}
</style>
<script>
import {
  listUser_access,
  getUser_access,
  delUser_access,
  addUser_access,
  updateUser_access,
  access,
  remoteUser, list_did_all,
} from "@/api/user_access/user_access";
import {MessageBox} from "element-ui";
import {Terminal} from "xterm";
import {FitAddon} from "xterm-addon-fit";
import "xterm/css/xterm.css";
import base58 from "bs58";
import {decodeBase64} from "tweetnacl-util";
import {
  getPropertyKeys,
  getPropertyValues,
} from "@/api/access_property/property";
import {delDid} from "@/api/did/did";

export default {
  name: "User_access",
  dicts: ["did_type", "on_chain"],
  data() {
    return {
      // 遮罩层
      loading: true,
      // 选中数组
      ids: [],
      // 非单个禁用
      single: true,
      // 非多个禁用
      multiple: true,
      // 显示搜索条件
      showSearch: true,
      // 总条数
      total: 0,
      // 用户访问控制表格数据
      user_accessList: [],
      didList: [],
      selectDid: "",
      // 弹出层标题
      title: "",
      sshUserInfo: {},
      // 是否显示弹出层
      open: false,
      openAccess: false,
      dialogVisible: false,
      term: null,
      socket: null,
      fitAddon: null,
      buffer: "",
      // 查询参数
      queryParams: {
        pageNum: 1,
        pageSize: 10,
        did: null,
        type: null,
        issuer: null,
        validFrom: null,
        validUntil: null,
      },
      // 表单参数
      form: {},
      formAccess: {
        userDID: "",
        deviceDID: "",
      },
      // 表单校验
      rules: {
        did: [
          {required: true, message: "DID不能为空", trigger: "blur"},
          {min: 10, message: "DID不能少于10位", trigger: "blur"},
        ],
        validFrom: [
          {required: true, message: "起始日期不能为空", trigger: "blur"},
        ],
        validUntil: [
          {required: true, message: "结束日期不能为空", trigger: "blur"},
        ],
        userProperty: [
          {required: true, message: "用户属性不能为空", trigger: "blur"},
        ],
      },
      rulesAccess: {
        deviceDID: [
          {required: true, message: "DID不能为空", trigger: "blur"},
          {min: 10, message: "DID不能少于10位", trigger: "blur"},
        ],
      },
      propertyKeys: [], // 属性名列表
      propertyValues: [], // 属性值列表（每个属性行对应一个数组）
      loadingKeys: false, // 属性名加载状态
      loadingValues: [], // 属性值加载状态（每个属性行对应一个状态）
    };
  },
  created() {
    this.getList();
    this.getAllDid();
  },
  methods: {
    /** 查询用户访问控制列表 */
    getList() {
      this.loading = true;
      listUser_access(this.queryParams).then((response) => {
        this.user_accessList = response.rows;
        this.total = response.total;
        this.loading = false;
      });
    },
    getAllDid() {
      list_did_all().then((response) => {
        this.didList = response.data;
        console.log(this.didList)
      });
    },
    // 加载属性名列表
    loadPropertyKeys() {
      this.loadingKeys = true;
      getPropertyKeys()
        .then((response) => {
          this.propertyKeys = response.data;
          this.loadingKeys = false;
        })
        .catch((error) => {
          console.error("获取属性名失败:", error);
          this.$message.error("获取属性名失败");
          this.loadingKeys = false;
        });
    },

    // 加载属性值列表
    loadPropertyValues(index) {
      const key = this.form.userProperties[index].key;
      if (!key) return;

      // 设置当前行的加载状态
      this.$set(this.loadingValues, index, true);

      getPropertyValues(key)
        .then((response) => {
          this.$set(this.propertyValues, index, response.data);
          this.$set(this.loadingValues, index, false);
        })
        .catch((error) => {
          console.error(`获取属性值失败: ${key}`, error);
          this.$message.error(`获取属性值失败: ${key}`);
          this.$set(this.propertyValues, index, []);
          this.$set(this.loadingValues, index, false);
        });
    },

    // 属性名变化时处理
    handleKeyChange(index) {
      // 清空当前属性值
      this.form.userProperties[index].value = "";
      // 加载新的属性值
      this.loadPropertyValues(index);
    },

    // 添加属性行
    addProperty() {
      this.form.userProperties.push({key: "", value: ""});
      // 初始化加载状态
      this.loadingValues.push(false);
      this.propertyValues.push([]);
    },

    // 删除属性行
    removeProperty(index) {
      this.form.userProperties.splice(index, 1);
      this.loadingValues.splice(index, 1);
      this.propertyValues.splice(index, 1);
    },

    // 解析用户属性字符串为数组
    parseUserProperty(property) {
      if (!property) return [];

      const result = [];
      const pairs = property.split(",");

      for (let pair of pairs) {
        const index = pair.indexOf(":");
        if (index !== -1) {
          const key = pair.substring(0, index).trim();
          const value = pair.substring(index + 1).trim();
          result.push({key, value});
        }
      }

      return result;
    },

    // 取消按钮
    cancel() {
      this.open = false;
      this.openAccess = false;
      this.reset();
    },
    // 表单重置
    reset() {
      this.form = {
        id: null,
        did: null,
        type: null,
        issuer: null,
        validFrom: null,
        validUntil: null,
        userProperties: [{key: "", value: ""}],
        userKeys: null,
        onChain: null,
        createBy: null,
        createTime: null,
        updateBy: null,
        updateTime: null,
      };
      this.formAccess = {
        did: null,
      };
      //this.resetForm("form");
      this.resetForm("formAccess");
      this.loadingValues = [false];
      this.propertyValues = [[]];
    },
    /** 搜索按钮操作 */
    handleQuery() {
      this.queryParams.pageNum = 1;
      this.getList();
    },
    /** 重置按钮操作 */
    resetQuery() {
      this.resetForm("queryForm");
      this.handleQuery();
    },
    // 多选框选中数据
    handleSelectionChange(selection) {
      this.ids = selection.map((item) => item.id);
      this.single = selection.length !== 1;
      this.multiple = !selection.length;
    },
    /** 新增按钮操作 */
    handleAdd() {
      this.reset();
      this.open = true;
      this.title = "添加用户访问控制";
      this.loadPropertyKeys();
    },
    /** 修改按钮操作 */
    handleUpdate(row) {
      this.reset();
      const id = row.id || this.ids;
      getUser_access(id).then((response) => {
        this.form = response.data;
        // 确保 userProperties 存在且是数组
        if (
          !this.form.userProperties ||
          !Array.isArray(this.form.userProperties)
        ) {
          this.form.userProperties = [];
        }

        // 如果存在 userProperty 字符串，解析为数组
        if (this.form.userProperty) {
          try {
            this.form.userProperties = this.parseUserProperty(
              this.form.userProperty
            );
          } catch (e) {
            console.error("解析用户属性失败:", e);
            this.form.userProperties = [{key: "", value: ""}];
          }
        }

        // 如果没有属性，添加一个空行
        if (this.form.userProperties.length === 0) {
          this.form.userProperties.push({key: "", value: ""});
        }

        // 初始化属性值加载状态
        this.loadingValues = new Array(this.form.userProperties.length).fill(
          false
        );
        this.propertyValues = new Array(this.form.userProperties.length).fill(
          []
        );

        // 加载属性名
        this.loadPropertyKeys();

        // 为每个已有属性加载属性值
        this.$nextTick(() => {
          this.form.userProperties.forEach((prop, index) => {
            if (prop.key) {
              this.loadPropertyValues(index);
            }
          });
        });
        this.open = true;
        this.title = "修改用户访问控制";
      });
    },
    /** 提交按钮 */
    submitForm() {
      this.$refs["form"].validate((valid) => {
        if (valid) {
          this.form.userProperty = this.form.userProperties
            .filter((p) => p.key && p.value)
            .map((p) => `${p.key}:${p.value}`)
            .join(",");
          if (this.form.id != null) {
            updateUser_access(this.form).then((response) => {
              this.$modal.msgSuccess("修改成功");
              this.open = false;
              this.getList();
            });
          } else {
            addUser_access(this.form).then((response) => {
              this.$modal.msgSuccess("新增成功");
              this.open = false;
              this.getList();
            });
          }
        }
      });
    },
    submitAccess(row) {
      this.formAccess.userDID = row.did;
      this.openAccess = true;
    },
    submitFormAccess() {
      this.$refs["formAccess"].validate((valid) => {
        if (valid) {

          access(this.formAccess).then((response) => {
            let deviceAccess = response.data;
            if (deviceAccess.accessType === 1) {
              MessageBox.confirm(deviceAccess.did + "的地址是: " + deviceAccess.secret, "解密成功", {
                confirmButtonText: '远程访问',
                cancelButtonText: '取消',
                type: "success",
              }).then(() => {
                // this.$modal.msgSuccess("远程访问");
                this.remoteUserCheck(this.formAccess)
              }).catch(() => {
              })
            } else {
              MessageBox.alert(deviceAccess.did + "的秘密是: " + deviceAccess.secret, "解密成功", {type: "success"});
            }
          });
        }
      });
    },
    remoteUserCheck(data) {
      remoteUser(data).then((response) => {
        console.log(response.data);
        this.sshUserInfo = response.data;
        this.$modal.notifySuccess("远程SSH公钥添加成功");
        this.openSSHDialog(this.formAccess);
      });
    },
    openSSHDialog() {
      this.dialogVisible = true;
    },
    initTerminal() {
      if (this.term) {
        this.fitAddon.fit();
        return;
      }

      this.term = new Terminal({
        rows: 24,
        cols: 80,
        cursorBlink: true,
        fontSize: 16,
        fontFamily: "monospace",
        theme: {
          background: "#000000",
          foreground: "#ffffff",
        },
        allowProposedApi: true,
        rendererType: "canvas", // 或 "dom"
      });

      this.fitAddon = new FitAddon();
      this.term.loadAddon(this.fitAddon);

      this.term.open(this.$refs.terminal);
      this.fitAddon.fit();
      let url =
        GLOBAL_WS_URL +
        "/ws/ssh" +
        "?userDID=" +
        this.formAccess.userDID +
        "&host=" + this.sshUserInfo.host;
      console.log(url);
      this.socket = new WebSocket(url);

      this.socket.onmessage = (event) => {
        let data = event.data;
        // data = base58.decode(data);
        console.log(data);
        // let decoder = new TextDecoder("utf-8");
        // let str = decoder.decode(data);
        // console.log("s:", str)
        this.term.write(data);
      };

      this.term.onData((data) => {
        // console.log(data);
        // this.socket.send(data);
        if (data === "\r") {
          // 回车
          console.log("buffer:", this.buffer);
          this.socket.send(this.buffer); // 把整行发给后端
          this.buffer = "";
          this.term.write("\r\n");
        } else if (data === "\x7F") {
          // 退格
          if (this.buffer.length > 0) {
            this.buffer = this.buffer.slice(0, -1);
            // 前端回显退格效果
            this.term.write("\b \b");
          }
        } else {
          this.buffer += data; // 缓存
          this.term.write(data); // 前端回显
        }
      });
      // 窗口大小调整时自适应
      window.addEventListener("resize", this.resizeTerminal);
    },
    resizeTerminal() {
      if (this.fitAddon) {
        this.fitAddon.fit();
      }
    },
    destroyTerminal() {
      if (this.socket) {
        this.socket.close();
        this.socket = null;
      }
      if (this.term) {
        this.term.dispose();
        this.term = null;
      }
      window.removeEventListener("resize", this.resizeTerminal);
    },
    /** 删除按钮操作 */
    handleDelete(row) {
      const ids = row.id || this.ids;
      this.$modal
        .confirm('是否确认删除用户访问控制编号为"' + ids + '"的数据项？')
        .then(function () {
          return delUser_access(ids);
        })
        .then(() => {
          this.getList();
          this.$modal.msgSuccess("删除成功");
        })
        .catch(() => {
        });
    },
    /** 导出按钮操作 */
    handleExport() {
      this.download(
        "access/user_access/export",
        {
          ...this.queryParams,
        },
        `user_access_${new Date().getTime()}.xlsx`
      );
    },
  },
};
</script>
